package com.loiot.baqi.utils.webSocket;


import java.io.IOException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.loiot.baqi.service.ZpAccountSalaryHistoryService;
import com.loiot.baqi.utils.Salary;
import com.loiot.baqi.utils.SpringBeanFactoryUtils;
import com.loiot.commons.utils.JsonUtil;
import com.timeloit.pojo.Account;


/**
 * -------------------------------------------
 * Title : ChatAnnotation 
 * Description : websocket服务相关
 * Create on : 2016年10月31日 下午5:35:22
 * Copyright (C) strongunion
 * @author RICK
 * 修改历史: 
 * 修改人 修改日期 修改描述
 * -------------------------------------------
 */
@ServerEndpoint(value = "/websocket/chat",configurator=GetHttpSessionConfigurator.class) 
public class ChatAnnotation {
	 private static final Log log = LogFactory.getLog(ChatAnnotation.class);  
	    /**用户登录集合*/
	    private static CopyOnWriteArraySet<ChatAnnotation> connections = new CopyOnWriteArraySet<ChatAnnotation>();
	    
	    /**websocket 本身的session*/
	    private Session session;
	    
	    /**当前要推送的用户ID*/
	    private static Long userId;
	    
	    /**要推送的用户ID*/
	    private static Long sourceId;
	  
	    /**
	     * TODO: 当用户会话打开的时候调用,默认推送预期薪资
	     * @Auhor: RICK
	     * @Date : 2016年10月31日
	     */
	    @OnOpen  
	    public void OnOpen(Session session,EndpointConfig config) {
	        this.session = session;
	        HttpSession httpSession= (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
	        Account  account = (Account)httpSession.getAttribute("com.loiot.baqi.shiro_session_user_key");
	    	userId = account.getAccountId();
    		connections.add(this);
			String msg = querySalaryDefalult(userId);
			broadcast(userId, msg);
	    }  
	    
	    /**
	     * TODO: 默认统计登录用户薪资
	     * @Auhor: RICK
	     * @Date : 2016年11月4日
	     */
	    public static String querySalaryDefalult(Long id){
	    	HashMap<String,Object> pMap = new HashMap<String,Object>();
    		pMap.put("earningPersonId", id);
    		Salary salary = new Salary();
    		String resultMsg = "";
    		try {
    			DecimalFormat dft  = new DecimalFormat("###0.00");
    			//薪资历史记录
    			ZpAccountSalaryHistoryService zpAccountSalaryHistoryService = (ZpAccountSalaryHistoryService)SpringBeanFactoryUtils.getBean("zpAccountSalaryHistoryService");
    			//统计用户所有的薪资
    			long totalAll = zpAccountSalaryHistoryService.getZpAccountSalaryHistorySum(pMap);
    			//统计用户本周的薪资
    			pMap.put("beingTime", getWeekFirstDay());
    			pMap.put("endTime", Calendar.getInstance().getTime());
    			long totalWeek = zpAccountSalaryHistoryService.getZpAccountSalaryHistorySum(pMap);
    			salary.setTotalAll(String.valueOf(dft.format(totalAll)));
    			salary.setTotalWeek(String.valueOf(dft.format(totalWeek)));
				resultMsg = JsonUtil.toJson(salary);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return resultMsg;
	    }
	    
	    
	    /**
	     * TODO: 当用户会话销毁的时候调用
	     * @Auhor: RICK
	     * @Date : 2016年10月31日
	     */
	    @OnClose  
	    public void onClose() {  
	        connections.remove(this);  
	    }  
	    
	    
	    /**
	     * TODO: 消息发送触发方法 
	     * @Auhor: RICK
	     * @Date : 2016年10月31日
	     */
	    @OnMessage  
	    public void onMessage(String message) {
	        broadcast(sourceId, message); 
	    }  
	  
	    /**
	     * TODO: websocket异常的时候调用
	     * @Auhor: RICK
	     * @Date : 2016年10月31日
	     */
	    @OnError  
	    public void onError(Throwable t) throws Throwable {  
	        log.error("Chat Error: " + t.toString(), t);  
	    }  
	  
	    /**
	     * TODO: 获取本周第一天的日期
	     * @Auhor: RICK
	     * @Date : 2016年10月24日
	     */
	    public static Date getWeekFirstDay(){
	    	Calendar cal = Calendar.getInstance();
	    	int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
	    	if (dayOfWeek == 1) {
	    		dayOfWeek = 6;
			} else {
				dayOfWeek = dayOfWeek - 2;
			}
	    	cal.add(Calendar.DATE, -dayOfWeek);
	    	return cal.getTime();
	    }
	    
	    
	  
	    
	    /**
	     * TODO: 消息广播方法 
	     * @param id
	     * @param msg
	     * @Auhor: RICK
	     * @Date : 2016年10月31日
	     */
	    private static void broadcast(Long id, String msg) {  
	    	if(userId != null){  
	    		sendToSingle(id ,msg);  
	        } else{  
	            sendToAll(msg);  
	        }  
	    }   
	    
	    /**
	     * TODO: 向指定用户发送薪资统计消息  
	     * @param id 用户id
	     * @param msg 推送消息
	     * @Auhor: RICK
	     * @Date : 2016年10月31日
	     */
	    public static void sendToSingleForSalary(Long id){
	    	if (connections.size() != 0) {
                for (ChatAnnotation s : connections) {
                    if (s != null) {
                        // 判断是否为终端信息。如果是终端信息则查询数据库获取detail
                            try {
                            	if (s.userId == id) {
                            		String msg = querySalaryDefalult(id);
                            		s.session.getBasicRemote().sendText(msg);
								}
							} catch (IOException e) {
								e.printStackTrace();
							}
                     }
	            }
		    }
	    }  
	      
	    /**
	     * TODO: 向指定用户发送消息  
	     * @param id 用户id
	     * @param msg 推送消息
	     * @Auhor: RICK
	     * @Date : 2016年10月31日
	     */
	    public static void sendToSingle(Long id, String msg){
	    	if (connections.size() != 0) {
                for (ChatAnnotation s : connections) {
                    if (s != null) {
                        // 判断是否为终端信息。如果是终端信息则查询数据库获取detail
                            try {
                            	if (s.userId == id) {
                            		s.session.getBasicRemote().sendText(msg);
								}
							} catch (IOException e) {
								e.printStackTrace();
							}
                     }
	            }
		    }
	    }  
	    
	    /**
	     * TODO: 部分推送
	     * @param idList 用户Id集合
	     * @param msg 推送消息
	     * @Auhor: RICK
	     * @Date : 2016年11月4日
	     */
	    public static void sendToPart(List<Long> idList,String msg){
	    	if (connections.size() != 0) {
	    		for (Long ids : idList) {
	    			for (ChatAnnotation s : connections) {
	                    if (s != null) {
	                        // 判断是否为终端信息。如果是终端信息则查询数据库获取detail
	                            try {
	                            	if (s.userId == ids) {
	                            		s.session.getBasicRemote().sendText(msg);
									}
								} catch (IOException e) {
									e.printStackTrace();
								}
	                     }
		            }
				}
                
		    }
	    }
	    
	    
	    /**
	     * TODO: 向所有用户发送 
	     * @Auhor: RICK
	     * @Date : 2016年10月31日
	     */
	    public static void sendToAll(String msg){
	    	if (connections.size() != 0) {
                for (ChatAnnotation s : connections) {
                    if (s != null) {
                        // 判断是否为终端信息。如果是终端信息则查询数据库获取detail
                            try {
								s.session.getBasicRemote().sendText(msg);
							} catch (IOException e) {
								e.printStackTrace();
							}
                     }
                }
	    	}
	    } 
	    
	    
	    
}
